from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
sys.path.append("../")
from drivers.driver_serial import *
from ui.Ui_Serial_Widget import Ui_Serial_Qwidget
import threading
from ui.MyFigure import MyFigure
import time
import csv
import os
from drivers.cimoread import *
import numpy as np
import serial
from 读取串口数据可以显示在上位机封装好的 import DataReceiver
# 测力计的代码

class MyWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_Serial_Qwidget()
        self.ui.setupUi(self)   
        self.device = ()
        self.device_name = ""
        self.band = 0
        self.start_event = threading.Event()
        self.stop_event = threading.Event()
        self.run_DataStart = None
        self.x_data = []
        self.y_data_x = []
        self.y_data_y = []
        self.y_data_z = []
        self.csv_file = None
        self.csv_writer = None
        self.data_1 = np.array([])
        self.data_mean=[0 for _ in range(3)]
        self.sum_data=[0 for _ in range(3)]
        self.init_ui()
    def Refresh(self):
        self.device = scan_serial_ports()
        if self.device:
            print("Available serial serial_ports:")
            for device, description in self.device:
                print(device, "-->", description)
        else:
            print("No serial serial_ports found.")
        device_name_0 = [i[0] for i in self.device]
        self.ui.comboBox.clear()
        self.ui.comboBox.addItems(device_name_0)

    def on_connect_clicked(self):
        if self.device:
            self.device_name = self.device[0][0]
            self.band = self.ui.comboBox_2.currentText()
            print(self.device_name, self.band)
        else:
            print("无端口！")
    def initialize_components(self, device_name, band):
        MLX90393_Data = DataReceiver(device_name, band, timeout=0.5)
        self.sum_data = [0.0] * 6
        for _ in range(10):#获取初始状态的是个数据，计算平均值
            data1, data2, data3,data4,data5,data6 = MLX90393_Data.read_single_frame()
            self.sum_data[0] += data1
            self.sum_data[1] += data2
            self.sum_data[2] += data3
            self.sum_data[3] += data4
            self.sum_data[4] += data5
            self.sum_data[5] += data6
        self.data_mean = [x / 10 for x in self.sum_data]#初始信号的平均值
        return MLX90393_Data
    def setup_csv(self):
        """
        设置CSV文件用于记录力数据。
        如果CSV文件不存在，则创建它并写入表头。
        无论文件是否存在，都会打开文件以供后续追加写入数据。
        """
        csv_filename = "force_data.csv"  # 定义CSV文件名
        if not os.path.exists(csv_filename):
            # 如果CSV文件不存在，则创建并写入表头
            with open(csv_filename, mode='w', newline='') as file:
                writer = csv.writer(file)
                writer.writerow(["Index", "ForceX", "ForceY", "ForceZ"])  # 调整CSV列名
        # 打开CSV文件以供追加数据
        self.csv_file = open(csv_filename, mode='a', newline='')
        self.csv_writer = csv.writer(self.csv_file)
    def collect_and_update(self, sensor_collector):
        try:
            self.data_1 = sensor_collector.read_single_frame()  # 采集数据，看需要的数据是几个，然后针对性的去选择数据
            self.data_1 = list(self.data_1)
            self.data_1 = [self.data_1[0]-self.data_mean[0],self.data_1[1]-self.data_mean[1],self.data_1[2]-self.data_mean[2],self.data_1[3]-self.data_mean[3],self.data_1[4]-self.data_mean[4],
                           self.data_1[5]-self.data_mean[5]]#去除初始状态的数据       
            # 判断数据的格式类型
            print(self.data_1)
            if len(self.data_1) >= 6 :
                x_val, z_val, y_val = self.data_1[:3]#x1z1y1
            else:
                print("数据格式错误，跳过本次更新")
                return
            # 更新绘图数据（使用实例变量，避免局部变量重置问题）
            self.x_data.append(len(self.x_data))  # X轴为递增索引
            self.y_data_x.append(x_val)
            self.y_data_y.append(y_val)
            self.y_data_z.append(z_val)
            # 实现滚动窗口：超过100点后移除最早的数据
            if len(self.x_data) > 100:
                self.x_data=[]
                self.y_data_x=[]
                self.y_data_y=[]
                self.y_data_z=[]
            # 发送信号到主线程更新UI（线程安全操作）
            self.plot_and_update(self.x_data,self.y_data_x,self.y_data_y,self.y_data_z)           
        except Exception as e:
            print(f"数据采集错误: {e}")
    #线程函数，采集数据在反复执行
    def run_DataStart_assist(self, device_name, band):
        sensor_collector = None
        try:
            sensor_collector= self.initialize_components(device_name, band)#实例化
            self.setup_csv()
            while not self.stop_event.is_set():
                self.start_event.wait()
                self.collect_and_update(sensor_collector)  # 传入实例化的对象
                time.sleep(0.1)          
        except serial.serialutil.SerialException as se:
            print(f"串口打开错误: {se}")
        except Exception as e:
            print(f"运行错误: {e}")
        finally:
            if self.csv_file:
                self.csv_file.close()
            if hasattr(sensor_collector, 'ser') and sensor_collector.ser.is_open:
                sensor_collector.ser.close()  # 关闭串口连接
    def plot_and_update(self,  x,y_x, y_y, y_z):
        if not hasattr(self, 'F1'):
            self.run_FigureStart_assist()
        if self.F1:
            self.F1.plotFig( x,y_x, y_y, y_z)  # 假设plotFig支持多曲线绘制
    def run_FigureStart_assist(self):
        self.F1 = MyFigure(width=5, height=4, dpi=100)
        width, height = self.ui.graphicsView.width(), self.ui.graphicsView.height()
        self.F1.setFixedSize(width, height)
        self.scene = QGraphicsScene()
        self.scene.addWidget(self.F1)
        self.ui.graphicsView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.ui.graphicsView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.ui.graphicsView.setScene(self.scene)
    def DataStart(self):
        self.start_event.set()
        self.stop_event.clear()
        if self.run_DataStart is None or not self.run_DataStart.is_alive():
            self.run_DataStart = threading.Thread(
                target=self.run_DataStart_assist, 
                args=(self.device_name, self.band),
                daemon=True
            )
        #线程中调用run_DataStart_assist
            self.run_DataStart.start()
        #开启图像的显示
        if not hasattr(self, 'F1'):
            self.run_FigureStart_assist()
    def DataStop(self):
        self.start_event.clear()
        self.stop_event.set()
        if self.run_DataStart is not None and self.run_DataStart.is_alive():
            self.run_DataStart.join()
    def init_ui(self):
        self.ui.pushButton.clicked.connect(self.Refresh)
        self.ui.pushButton_2.clicked.connect(self.on_connect_clicked)
        self.ui.pushButton_3.clicked.connect(self.DataStart)
        self.ui.pushButton_4.clicked.connect(self.DataStop)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWidget()
    window.show()
    sys.exit(app.exec_())